package com.gitee.openviducn.inspector.cdr.process;

import com.gitee.openviducn.inspector.enums.CDREventEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Webhook的CDR处理器注册管理
 * @Author: https://gitee.com/wesleyOne
 * @Date: 02.29 2020
 */
@Slf4j
@Component
public class WebhookCDRProcessorManager implements ApplicationContextAware, InitializingBean {

    private ConcurrentHashMap<String, BaseWebhookCDRProcessor> processorMap = new ConcurrentHashMap<>(16);

    private ApplicationContext ctx;

    @Override
    public void setApplicationContext(ApplicationContext ctx) throws BeansException {
        this.ctx = ctx;
    }

    @Override
    public void afterPropertiesSet() {
        Map<String, Object> processors = ctx.getBeansWithAnnotation(WebhookCDRProcessor.class);
        if (CollectionUtils.isNotEmpty(processors.values())) {
            log.info("=============webhook处理器 加载开始================");
            for (Object confBean : processors.values()) {
                Class<?> clz = confBean.getClass();
                // 解决CGLIB代理问题(借鉴elastic-job-spring-boot-starter项目处理)
                String interfaceName = clz.getInterfaces()[0].getSimpleName();
                if (!"BaseWebhookCDRProcessor".contains(interfaceName)) {
                    clz = clz.getSuperclass();
                }
                WebhookCDRProcessor annotation = AnnotationUtils.findAnnotation(clz, WebhookCDRProcessor.class);
                if (Objects.isNull(annotation)) {
                    log.warn("webhook处理器-未指定注解 {}", clz.getSimpleName());
                    continue;
                }
                CDREventEnum event = annotation.event();
                String code = event.getCode();
                if (processorMap.containsKey(code)) {
                    throw new IllegalStateException("Webhook的CDR处理器存在相同类型名称:".concat(code));
                }
                processorMap.put(code, (BaseWebhookCDRProcessor)confBean);
                log.info("webhook处理器-成功加载 {} {}",event.getDesc(), clz.getSimpleName());
            }
            log.info("=============webhook处理器 加载结束================");
        }
    }

    /**
     * 初始化后获取处理器
     * @return 处理器缓存
     */
    public BaseWebhookCDRProcessor getProcessor(String type) {
        return this.processorMap.get(type);
    }
}
